#include <bits/stdc++.h>

#define in read()
#define pb push_back
#define vec vector<int>

using namespace std;

int read(){int x = 0,sgn = 1;char ch = getchar();for(;!isdigit(ch);ch = getchar()) if(ch == '-') sgn = -1;for(;isdigit(ch);ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48); return x * sgn;}

const int N = 1e5+10;

int n,m,a[N];
int dfn[N],siz[N],son[N],top[N],fa[N],ind[N],tim,dep[N];
vec G[N];

struct node{
	int lv,rv,s;
	node(int _l = 0,int _r = 0,int _s = 0):lv(_l),rv(_r),s(_s){}
	friend node operator + (node a,node b){return node(a.lv,b.rv,a.s + b.s - (a.rv == b.lv));}
}val[N<<2];

int cov[N<<2];

void dfs(int x,int p){
	dep[x] = dep[p] + 1; siz[x] = 1;fa[x] = p;
	for(int y : G[x]) if(y ^ fa[x]) dfs(y,x), siz[x] += siz[y],son[x] = siz[y] > siz[son[x]] ? y : son[x];
}

void dfs1(int x,int anc){
	dfn[x] = ++tim; top[x] = anc; ind[dfn[x]] = x; if(son[x]) dfs1(son[x],anc);
	for(int y : G[x]) if(y ^ fa[x] && y ^ son[x]) dfs1(y,y);
}

void col(int o,int x){cov[o] = 1; val[o].lv = val[o].rv = x; val[o].s = 1; cov[o] = x; }

void pushdown(int o){if(cov[o]){col(o << 1,cov[o]); col(o << 1 | 1,cov[o]); cov[o] = 0;}}

void build(int o = 1,int l = 1,int r = n){
	if(l == r) return col(o,a[ind[l]]),void(); int mid = l + r >> 1;
	build(o << 1,l,mid); build(o << 1 | 1,mid + 1,r); val[o] = val[o << 1] + val[o << 1 | 1];
}

void upd(int xl,int xr,int v,int o = 1,int l = 1,int r = n){
	if(xl == l && xr == r) return col(o,v),void(); int mid = l + r >> 1; pushdown(o);
	if(xr <= mid) upd(xl,xr,v,o << 1,l,mid); else if(xl > mid) upd(xl,xr,v,o << 1 | 1,mid + 1,r);
	else upd(xl,mid,v,o << 1,l,mid),upd(mid + 1,xr,v,o << 1 | 1,mid + 1,r); val[o] = val[o << 1] + val[o << 1 | 1];
}

node query(int xl,int xr,int o = 1,int l = 1,int r = n){
	if(xl == l && xr == r) return val[o]; int mid = l + r >> 1; pushdown(o);
	if(xr <= mid) return query(xl,xr,o<<1,l,mid); else if(xl > mid) return query(xl,xr,o << 1| 1,mid + 1,r);
	else return query(xl,mid,o<<1,l,mid) + query(mid + 1,xr,o << 1 | 1,mid + 1,r);
}

void modify(int x,int y,int c){
	while(top[x] ^ top[y]){
		if(dep[top[x]] < dep[top[y]]) swap(x,y);
		upd(dfn[top[x]],dfn[x],c); x = fa[top[x]];
	}
	if(dfn[x] > dfn[y]) swap(x,y); upd(dfn[x],dfn[y],c);
}

int qry(int x,int y){
	node t1,t2;
	while(top[x] ^ top[y]){
		if(dep[top[x]] < dep[top[y]]) swap(x,y),swap(t1,t2);
		t1 = query(dfn[top[x]],dfn[x]) + t1; x = fa[top[x]];
	}
	if(dfn[x] > dfn[y]) swap(x,y),swap(t1,t2); node t3 = query(dfn[x],dfn[y]);
	swap(t1.lv,t1.rv); return (t1 + t3 + t2).s;
}

char get(){char ch = getchar(); while(!isalpha(ch)) ch = getchar();return ch;}

int main(){
#ifndef ONLINE_JUDGE
	freopen("1.in","r",stdin);
#endif
	n = in,m = in; for(int i = 1;i <= n;i++) a[i] = in;
	for(int i = 1,u,v;i < n;i++) u = in,v = in,G[u].pb(v),G[v].pb(u);
	dfs(1,0); dfs1(1,1); build();
	while(m--){
		char op = get(); int a = in,b = in,c;
		if(op == 'C') c = in,modify(a,b,c);
		else printf("%d\n",qry(a,b));
	}
	return 0;
}
